package meiyunting.shiwuzhaoling.controller;

import meiyunting.shiwuzhaoling.model.User;
import meiyunting.shiwuzhaoling.model.UserRole;
import meiyunting.shiwuzhaoling.repository.UserRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.time.LocalDateTime;
import java.util.HashMap;
import java.util.Map;
import java.util.Optional;

import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;

@RestController
@RequestMapping("/api/test")
public class TestController {

    private final UserRepository userRepository;
    private final PasswordEncoder passwordEncoder;
    private final JdbcTemplate jdbcTemplate;
    private final UserDetailsService userDetailsService;

    @Autowired
    public TestController(UserRepository userRepository, PasswordEncoder passwordEncoder, JdbcTemplate jdbcTemplate, UserDetailsService userDetailsService) {
        this.userRepository = userRepository;
        this.passwordEncoder = passwordEncoder;
        this.jdbcTemplate = jdbcTemplate;
        this.userDetailsService = userDetailsService;
    }

    @GetMapping("/create-admin")
    public Map<String, Object> createAdmin() {
        Map<String, Object> response = new HashMap<>();
        
        try {
            // 检查管理员是否已存在
            Optional<User> existingAdmin = userRepository.findByUsername("admin");
            
            if (existingAdmin.isPresent()) {
                // 更新现有管理员密码
                User admin = existingAdmin.get();
                String encodedPassword = passwordEncoder.encode("admin123");
                admin.setPassword(encodedPassword);
                admin.setRole(UserRole.ADMIN);
                admin.setUpdatedAt(LocalDateTime.now());
                userRepository.save(admin);
                
                response.put("success", true);
                response.put("message", "管理员账号已存在，密码已重置为admin123");
                response.put("username", admin.getUsername());
                response.put("role", admin.getRole().name());
            } else {
                // 创建新管理员
                User admin = new User();
                admin.setUsername("admin");
                admin.setPassword(passwordEncoder.encode("admin123"));
                admin.setEmail("admin@example.com");
                admin.setRole(UserRole.ADMIN);
                admin.setCreatedAt(LocalDateTime.now());
                admin.setUpdatedAt(LocalDateTime.now());
                
                userRepository.save(admin);
                
                response.put("success", true);
                response.put("message", "管理员账号创建成功");
                response.put("username", admin.getUsername());
                response.put("role", admin.getRole().name());
            }
        } catch (Exception e) {
            response.put("success", false);
            response.put("message", "创建管理员账号失败: " + e.getMessage());
            e.printStackTrace();
        }
        
        return response;
    }
    
    @GetMapping("/reset-admin-password")
    public Map<String, Object> resetAdminPassword() {
        Map<String, Object> response = new HashMap<>();
        
        try {
            // 检查管理员是否已存在
            Optional<User> existingAdmin = userRepository.findByUsername("admin");
            
            if (existingAdmin.isPresent()) {
                // 直接设置一个明确的密码值，不使用加密
                User admin = existingAdmin.get();
                
                // 使用BCrypt直接设置一个已知的加密密码值
                // 这是"admin123"的BCrypt加密值
                admin.setPassword("$2a$10$8CU8Z5yzd.oZuuXxNI4Oye8wGMLKlSQ/ZCvs2xHrFcJHGKx/tKkMi");
                admin.setRole(UserRole.ADMIN);
                admin.setUpdatedAt(LocalDateTime.now());
                userRepository.save(admin);
                
                response.put("success", true);
                response.put("message", "管理员密码已直接重置为admin123（使用预设的加密值）");
                response.put("username", admin.getUsername());
                response.put("role", admin.getRole().name());
                response.put("passwordHash", admin.getPassword());
            } else {
                // 创建新管理员，直接使用预设的加密密码
                User admin = new User();
                admin.setUsername("admin");
                admin.setPassword("$2a$10$8CU8Z5yzd.oZuuXxNI4Oye8wGMLKlSQ/ZCvs2xHrFcJHGKx/tKkMi");
                admin.setEmail("admin@example.com");
                admin.setRole(UserRole.ADMIN);
                admin.setCreatedAt(LocalDateTime.now());
                admin.setUpdatedAt(LocalDateTime.now());
                
                userRepository.save(admin);
                
                response.put("success", true);
                response.put("message", "管理员账号创建成功，密码设置为admin123");
                response.put("username", admin.getUsername());
                response.put("role", admin.getRole().name());
                response.put("passwordHash", admin.getPassword());
            }
        } catch (Exception e) {
            response.put("success", false);
            response.put("message", "重置管理员密码失败: " + e.getMessage());
            e.printStackTrace();
        }
        
        return response;
    }
    
    @GetMapping("/check-admin")
    public Map<String, Object> checkAdmin() {
        Map<String, Object> response = new HashMap<>();
        
        try {
            Optional<User> admin = userRepository.findByUsername("admin");
            
            if (admin.isPresent()) {
                User adminUser = admin.get();
                response.put("exists", true);
                response.put("username", adminUser.getUsername());
                response.put("email", adminUser.getEmail());
                response.put("role", adminUser.getRole().name());
                response.put("created_at", adminUser.getCreatedAt());
                response.put("password_hash", adminUser.getPassword());
            } else {
                response.put("exists", false);
                response.put("message", "管理员账号不存在");
            }
            
            response.put("success", true);
        } catch (Exception e) {
            response.put("success", false);
            response.put("message", "检查管理员账号失败: " + e.getMessage());
            e.printStackTrace();
        }
        
        return response;
    }
    
    @GetMapping("/sql-reset-admin")
    public Map<String, Object> sqlResetAdmin() {
        Map<String, Object> response = new HashMap<>();
        
        try {
            // 先检查admin用户是否存在
            Integer count = jdbcTemplate.queryForObject(
                "SELECT COUNT(*) FROM users WHERE username = 'admin'", Integer.class);
            
            if (count != null && count > 0) {
                // 更新现有管理员账号
                int updated = jdbcTemplate.update(
                    "UPDATE users SET password = ?, role = 'ADMIN', updated_at = NOW() WHERE username = 'admin'",
                    "$2a$10$8CU8Z5yzd.oZuuXxNI4Oye8wGMLKlSQ/ZCvs2xHrFcJHGKx/tKkMi"
                );
                
                response.put("success", true);
                response.put("message", "管理员密码已通过SQL直接重置");
                response.put("updated", updated);
            } else {
                // 创建新管理员账号
                int inserted = jdbcTemplate.update(
                    "INSERT INTO users (username, password, email, role, created_at, updated_at) VALUES (?, ?, ?, ?, NOW(), NOW())",
                    "admin", "$2a$10$8CU8Z5yzd.oZuuXxNI4Oye8wGMLKlSQ/ZCvs2xHrFcJHGKx/tKkMi", "admin@example.com", "ADMIN"
                );
                
                response.put("success", true);
                response.put("message", "管理员账号已通过SQL直接创建");
                response.put("inserted", inserted);
            }
            
            // 检查结果
            Map<String, Object> admin = jdbcTemplate.queryForMap(
                "SELECT * FROM users WHERE username = 'admin'"
            );
            
            response.put("admin", admin);
            
        } catch (Exception e) {
            response.put("success", false);
            response.put("message", "SQL重置管理员失败: " + e.getMessage());
            e.printStackTrace();
        }
        
        return response;
    }
    
    @GetMapping("/test-login")
    public Map<String, Object> testLogin() {
        Map<String, Object> response = new HashMap<>();
        
        try {
            // 获取管理员账号
            Optional<User> adminOpt = userRepository.findByUsername("admin");
            
            if (!adminOpt.isPresent()) {
                response.put("success", false);
                response.put("message", "管理员账号不存在");
                return response;
            }
            
            User admin = adminOpt.get();
            
            // 测试密码匹配
            boolean passwordMatches = passwordEncoder.matches("admin123", admin.getPassword());
            
            response.put("username", admin.getUsername());
            response.put("passwordHash", admin.getPassword());
            response.put("passwordMatches", passwordMatches);
            
            // 尝试加载UserDetails
            try {
                UserDetails userDetails = userDetailsService.loadUserByUsername("admin");
                response.put("userDetailsLoaded", true);
                response.put("authorities", userDetails.getAuthorities());
                response.put("userDetailsPassword", userDetails.getPassword());
            } catch (Exception e) {
                response.put("userDetailsLoaded", false);
                response.put("userDetailsError", e.getMessage());
            }
            
            response.put("success", true);
            
        } catch (Exception e) {
            response.put("success", false);
            response.put("message", "测试登录失败: " + e.getMessage());
            e.printStackTrace();
        }
        
        return response;
    }
    
    @GetMapping("/check-current-user")
    public Map<String, Object> checkCurrentUser() {
        Map<String, Object> response = new HashMap<>();
        
        try {
            // 获取当前认证信息
            org.springframework.security.core.Authentication auth = 
                SecurityContextHolder.getContext().getAuthentication();
            
            if (auth != null && auth.isAuthenticated() && 
                !auth.getPrincipal().equals("anonymousUser")) {
                
                response.put("authenticated", true);
                response.put("username", auth.getName());
                response.put("authorities", auth.getAuthorities());
                response.put("principal", auth.getPrincipal().toString());
                response.put("details", auth.getDetails());
                
                // 检查是否有ROLE_ADMIN权限
                boolean isAdmin = auth.getAuthorities().stream()
                    .anyMatch(a -> a.getAuthority().equals("ROLE_ADMIN"));
                response.put("isAdmin", isAdmin);
                
            } else {
                response.put("authenticated", false);
                response.put("message", "用户未登录或匿名用户");
            }
            
            response.put("success", true);
            
        } catch (Exception e) {
            response.put("success", false);
            response.put("message", "检查当前用户失败: " + e.getMessage());
            e.printStackTrace();
        }
        
        return response;
    }

    @GetMapping("/check-profile-access")
    public Map<String, Object> checkProfileAccess() {
        Map<String, Object> response = new HashMap<>();
        
        try {
            // 获取当前认证信息
            Authentication auth = SecurityContextHolder.getContext().getAuthentication();
            
            if (auth != null && auth.isAuthenticated() && 
                !auth.getPrincipal().equals("anonymousUser")) {
                
                response.put("authenticated", true);
                response.put("username", auth.getName());
                response.put("canAccessProfile", true);
                response.put("message", "用户已登录，可以访问个人中心");
                
            } else {
                response.put("authenticated", false);
                response.put("canAccessProfile", false);
                response.put("message", "用户未登录，无法访问个人中心");
            }
            
            response.put("success", true);
            
        } catch (Exception e) {
            response.put("success", false);
            response.put("message", "检查个人中心访问权限失败: " + e.getMessage());
            e.printStackTrace();
        }
        
        return response;
    }

    @GetMapping("/test-chinese-username")
    public Map<String, Object> testChineseUsername() {
        Map<String, Object> response = new HashMap<>();
        
        try {
            // 尝试创建带中文用户名的用户
            String chineseUsername = "测试用户" + System.currentTimeMillis();
            User user = new User();
            user.setUsername(chineseUsername);
            user.setPassword(passwordEncoder.encode("password123"));
            user.setEmail("test" + System.currentTimeMillis() + "@example.com");
            user.setRole(UserRole.USER);
            user.setCreatedAt(LocalDateTime.now());
            user.setUpdatedAt(LocalDateTime.now());
            
            User savedUser = userRepository.save(user);
            
            response.put("success", true);
            response.put("message", "成功创建带中文用户名的用户");
            response.put("savedUser", savedUser);
            
            // 查询以验证存储正确
            Optional<User> retrievedUser = userRepository.findByUsername(chineseUsername);
            if (retrievedUser.isPresent()) {
                response.put("retrievedUser", retrievedUser.get());
                response.put("usernameMatch", chineseUsername.equals(retrievedUser.get().getUsername()));
            } else {
                response.put("error", "无法通过用户名检索用户");
            }
            
        } catch (Exception e) {
            response.put("success", false);
            response.put("error", e.getMessage());
            e.printStackTrace();
        }
        
        return response;
    }
} 